/*
 * %W% %E%
 * 
 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package com.sun.corba.se.impl.transport;

import java.nio.channels.SelectionKey;

import org.omg.CORBA.INTERNAL;

import com.sun.corba.se.pept.transport.Acceptor;
import com.sun.corba.se.pept.transport.Connection;
import com.sun.corba.se.pept.transport.EventHandler;

import com.sun.corba.se.spi.orb.ORB;
import com.sun.corba.se.spi.orbutil.threadpool.NoSuchThreadPoolException;
import com.sun.corba.se.spi.orbutil.threadpool.NoSuchWorkQueueException;
import com.sun.corba.se.spi.orbutil.threadpool.Work;

import com.sun.corba.se.impl.orbutil.ORBUtility;

public abstract class EventHandlerBase
    implements
	EventHandler
{
    protected ORB orb;
    protected Work work;
    protected boolean useWorkerThreadForEvent;
    protected boolean useSelectThreadToWait;
    protected SelectionKey selectionKey;

    ////////////////////////////////////////////////////
    //
    // EventHandler methods
    //

    public void setUseSelectThreadToWait(boolean x)
    {
	useSelectThreadToWait = x;
    }

    public boolean shouldUseSelectThreadToWait()
    {
	return useSelectThreadToWait;
    }

    public void setSelectionKey(SelectionKey selectionKey)
    {
	this.selectionKey = selectionKey;
    }

    public SelectionKey getSelectionKey()
    {
	return selectionKey;
    }

    /*
     * NOTE:
     * This is not thread-safe by design.
     * Only one thread should call it - a reader/listener/select thread.
     * Not stateless: interest ops, registration.
     */
    public void handleEvent()
    {
	if (orb.transportDebugFlag) {
	    dprint(".handleEvent->: " + this);
	}
	getSelectionKey().interestOps(getSelectionKey().interestOps() &
				      (~ getInterestOps()));
	if (shouldUseWorkerThreadForEvent()) {
	    Throwable throwable = null;
	    try {
		if (orb.transportDebugFlag) {
		    dprint(".handleEvent: addWork to pool: " + 0);
		}
		orb.getThreadPoolManager().getThreadPool(0)
		    .getWorkQueue(0).addWork(getWork());
	    } catch (NoSuchThreadPoolException e) {
		throwable = e;
	    } catch (NoSuchWorkQueueException e) {
		throwable = e;
	    }
	    // REVISIT: need to close connection.
	    if (throwable != null) {
		if (orb.transportDebugFlag) {
		    dprint(".handleEvent: " + throwable);
		}
		INTERNAL i = new INTERNAL("NoSuchThreadPoolException");
		i.initCause(throwable);
		throw i;
	    }
	} else {
	    if (orb.transportDebugFlag) {
		dprint(".handleEvent: doWork");
	    }
	    getWork().doWork();
	}
	if (orb.transportDebugFlag) {
	    dprint(".handleEvent<-: " + this);
	}
    }

    public boolean shouldUseWorkerThreadForEvent()
    {
	return useWorkerThreadForEvent;
    }

    public void setUseWorkerThreadForEvent(boolean x)
    {
	useWorkerThreadForEvent = x;
    }

    public void setWork(Work work)
    {
	this.work = work;
    }

    public Work getWork()
    {
	return work;
    }

    private void dprint(String msg)
    {
	ORBUtility.dprint("EventHandlerBase", msg);
    }
}

// End of file.
